#include <memory>

#include "Socket.hpp"
#include "Protocol.hpp"
#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculate.hpp"

// void Handler(Net_work::Socket* Socket,std::string ip,uint16_t port)
// {
//     while(true)
//     {
//         struct Protocol::Request req;
//         int  n = recv(Socket->GetSockFd(),&req,sizeof req,0);
//         if(n<=0)
//         break;
//         std::cout<<"["<<ip<<"]:["<<port<<"]: ";
//         req.Debug();
//     }
// }

std::string HandlerRequest(std::string &inbufferstream, std::string ip, uint16_t port, bool *flag)
{
    *flag = true;  // 默认是正常的，没有出错

    // 创建一个计算类，公用的
    CalCulate_Ns::Calculate g_CalCulate;

    // 构建一个工厂
    std::unique_ptr<Protocol::Factory> factory = std::make_unique<Protocol::Factory>();

    // 返回一个  智能指针 Request 的请求
    auto req = factory->BuildRequest();

    std::string message,Sum_Message;

    while (true)
    {
        // // 1. 读取报文
        // if(!Socket->Recv(&inbufferstream,default_Size))
        // break;  // 只有将缓冲区读取干净才会退出

        // 2. 对读取到的信息分析是否有完整的报文
        

        // if(!Protocol::Decode(inbufferstream,&message))  // 如果报文不完整，则继续读取，直到读取完毕
        // continue;

                                    // message 每次都会刷新新的 message
        while (Protocol::Decode(inbufferstream, &message)) // 如果报文不完整，则继续读取，直到读取完毕
        {    // 如果解析一个报文成功，将其处理完毕后，继续解析报文，直到没有一个完整的报文读取，那么就退出，让 Socket 从缓冲区重新读取新的报文

           

            // 3. 进行反序列化 ， 转换成操作数才能继续计算
            if (!req->DeSerialize(message)) // 如果反序列化失败，说明发送的报文有问题，直接退出
            {
                *flag = 0;
                return "";
            }

            // 4. 业务处理
            auto resp = g_CalCulate.Cal(req); // 计算结果

            // 5. 序列化 response (结果)
            std::string send_message;
            resp->Serialize(&send_message);

            // 6. 构建返回给客户端的相应报文
            Sum_Message += Protocol::Encode(send_message);
        }

            // 7. 发送报文
            // 返回给 Tcp_Server 让其发送
        return Sum_Message;
        
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage->  " << argv[0] << " port" << std::endl;
        return 0;
    }

    uint16_t localport = std::stoi(argv[1]);

    std::unique_ptr<TcpServer> Tcp_server = std::make_unique<TcpServer>(localport, HandlerRequest);

    Tcp_server->Loop();
}

// int main(int argc, char *argv[])
// {
//     if (argc != 2)
//     {
//         std::cout << "Usage->  " << argv[0] << " port" << std::endl;
//         return 0;
//     }

//     uint16_t localport = std::stoi(argv[1]);

//     Socket *listensock = new TcpSocket();

//     listensock->BuildListenSocket(localport, backlog);

//     while (true)
//     {
//         std::string peerip;
//         uint16_t peerport;
//         Socket *newsock = listensock->AcceptConnection(&peerip, &peerport);

//         std::cout << "get a new connection,sockfd: " << newsock->GetSockFd()
//                   << " client ifo: " << peerip << ":" << peerport << std::endl;

//         sleep(5);

//         newsock->CloseSocket();
//     }
// }